<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>信号量 - FreeRTOS学习笔记</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f4f4f4;
        }

        header {
            background: linear-gradient(135deg, #2c3e50, #3498db);
            color: white;
            text-align: center;
            padding: 2rem 0;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }

        h1 {
            font-size: 2.5rem;
            margin-bottom: 0.5rem;
        }

        .subtitle {
            font-size: 1.2rem;
            opacity: 0.9;
        }

        nav {
            background-color: #2c3e50;
            padding: 0;
            position: sticky;
            top: 0;
            z-index: 100;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }

        nav ul {
            list-style: none;
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
        }

        nav li {
            margin: 0;
        }

        nav a {
            display: block;
            color: white;
            text-decoration: none;
            padding: 1rem 1.5rem;
            transition: background-color 0.3s;
        }

        nav a:hover {
            background-color: #3498db;
        }

        .container {
            max-width: 1200px;
            margin: 2rem auto;
            padding: 0 2rem;
        }

        .content {
            background-color: white;
            border-radius: 8px;
            padding: 2rem;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        section {
            margin-bottom: 3rem;
        }

        h2 {
            color: #2c3e50;
            border-bottom: 2px solid #3498db;
            padding-bottom: 0.5rem;
            margin-bottom: 1.5rem;
        }

        h3 {
            color: #3498db;
            margin: 1.5rem 0 1rem;
        }

        h4 {
            color: #2c3e50;
            margin: 1rem 0 0.5rem;
        }

        p {
            margin-bottom: 1rem;
        }

        ul, ol {
            margin-left: 2rem;
            margin-bottom: 1rem;
        }

        li {
            margin-bottom: 0.5rem;
        }

        pre {
            background-color: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 4px;
            padding: 1rem;
            overflow-x: auto;
            margin: 1rem 0;
        }

        code {
            font-family: 'Courier New', monospace;
            background-color: #f8f9fa;
            padding: 0.2rem 0.4rem;
            border-radius: 3px;
            font-size: 0.9rem;
        }

        pre code {
            background-color: transparent;
            padding: 0;
        }

        .function-signature {
            background-color: #e8f4fc;
            border-left: 4px solid #3498db;
            padding: 1rem;
            margin: 1rem 0;
            border-radius: 0 4px 4px 0;
        }

        .footer {
            text-align: center;
            padding: 2rem;
            background-color: #2c3e50;
            color: white;
            margin-top: 2rem;
        }

        .nav-links {
            display: flex;
            justify-content: space-between;
            margin-top: 2rem;
        }

        .nav-links a {
            text-decoration: none;
            color: #3498db;
            font-weight: bold;
            padding: 0.5rem 1rem;
            border: 1px solid #3498db;
            border-radius: 4px;
        }

        .nav-links a:hover {
            background-color: #3498db;
            color: white;
        }

        @media (max-width: 768px) {
            nav ul {
                flex-direction: column;
            }

            .container {
                padding: 0 1rem;
            }

            h1 {
                font-size: 2rem;
            }
        }
    </style>
    <!-- 引入浮动笔记窗口脚本 -->
    <script src="float-notes.js"></script>
</head>
<body>
    <header>
        <h1>FreeRTOS学习笔记</h1>
        <p class="subtitle">第六章：信号量</p>
    </header>

    <nav>
        <ul>
            <li><a href="index.html">主页</a></li>
            <li><a href="chapter1.html">基础知识</a></li>
            <li><a href="chapter2.html">任务管理</a></li>
            <li><a href="chapter3.html">任务调度</a></li>
            <li><a href="chapter4.html">内存管理</a></li>
            <li><a href="chapter5.html">队列</a></li>
            <li><a href="chapter6.html">信号量</a></li>
            <li><a href="chapter7.html">软件定时器</a></li>
            <li><a href="image_gallery.html">图片资源</a></li>
        </ul>
    </nav>

    <div class="container">
        <div class="content">
            <section id="semaphores">
                <h2>6. 信号量</h2>
                
                <h3>6.1 信号量类型详解</h3>
                
                <h4>二值信号量</h4>
                <ul>
                    <li>只有0和1两个状态</li>
                    <li>主要用于任务同步和中断同步</li>
                    <li>不支持优先级继承，可能引起优先级翻转</li>
                </ul>
                
                <h4>计数型信号量</h4>
                <ul>
                    <li>可以表示多个资源</li>
                    <li>用于资源管理和事件计数</li>
                    <li>计数值表示可用资源数量</li>
                </ul>
                
                <h4>互斥信号量</h4>
                <ul>
                    <li>专为互斥访问设计</li>
                    <li>支持优先级继承，解决优先级翻转问题</li>
                    <li>不能在中断服务程序中使用</li>
                </ul>
                
                <h3>6.2 优先级翻转问题</h3>
                
                <h4>问题描述</h4>
                <ul>
                    <li>高优先级任务因等待资源被低优先级任务阻塞</li>
                    <li>中等优先级任务抢占CPU，导致高优先级任务迟迟得不到执行</li>
                </ul>
                
                <h4>解决方案</h4>
                <ul>
                    <li>使用互斥信号量的优先级继承机制</li>
                    <li>临时提升占用资源的低优先级任务优先级</li>
                </ul>
                
                <h3>6.3 信号量相关函数详解</h3>
                
                <h4>xSemaphoreCreateBinary - 创建二值信号量</h4>
                <div class="function-signature">
                    <pre><code>SemaphoreHandle_t xSemaphoreCreateBinary(void);</code></pre>
                </div>
                
                <p><strong>返回值</strong>：</p>
                <ul>
                    <li>成功：信号量句柄</li>
                    <li>失败：NULL</li>
                </ul>
                
                <p><strong>作用</strong>：创建一个二值信号量，初始状态为空（不可用）</p>
                
                <p><strong>示例</strong>：</p>
                <pre><code>// 创建二值信号量
SemaphoreHandle_t xBinarySemaphore = xSemaphoreCreateBinary();

if (xBinarySemaphore != NULL) {
    // 信号量创建成功
    // 可以在中断中"给出"信号量
} else {
    // 信号量创建失败
}</code></pre>
                
                <h4>xSemaphoreCreateCounting - 创建计数型信号量</h4>
                <div class="function-signature">
                    <pre><code>SemaphoreHandle_t xSemaphoreCreateCounting(
    UBaseType_t uxMaxCount,       // 最大计数值
    UBaseType_t uxInitialCount    // 初始计数值
);</code></pre>
                </div>
                
                <p><strong>返回值</strong>：</p>
                <ul>
                    <li>成功：信号量句柄</li>
                    <li>失败：NULL</li>
                </ul>
                
                <p><strong>作用</strong>：创建一个计数型信号量</p>
                
                <p><strong>示例</strong>：</p>
                <pre><code>// 创建计数型信号量，最大计数5，初始计数0
SemaphoreHandle_t xCountingSemaphore = xSemaphoreCreateCounting(5, 0);

if (xCountingSemaphore != NULL) {
    // 信号量创建成功
} else {
    // 信号量创建失败
}</code></pre>
                
                <h4>xSemaphoreCreateMutex - 创建互斥信号量</h4>
                <div class="function-signature">
                    <pre><code>SemaphoreHandle_t xSemaphoreCreateMutex(void);</code></pre>
                </div>
                
                <p><strong>返回值</strong>：</p>
                <ul>
                    <li>成功：信号量句柄</li>
                    <li>失败：NULL</li>
                </ul>
                
                <p><strong>作用</strong>：创建一个互斥信号量</p>
                
                <p><strong>示例</strong>：</p>
                <pre><code>// 创建互斥信号量
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();

if (xMutex != NULL) {
    // 互斥信号量创建成功
} else {
    // 互斥信号量创建失败
}</code></pre>
                
                <h4>xSemaphoreTake - 获取信号量</h4>
                <div class="function-signature">
                    <pre><code>BaseType_t xSemaphoreTake(
    SemaphoreHandle_t xSemaphore, // 信号量句柄
    TickType_t xBlockTime         // 阻塞等待时间
);</code></pre>
                </div>
                
                <p><strong>返回值</strong>：</p>
                <ul>
                    <li>pdTRUE: 成功获取信号量</li>
                    <li>pdFALSE: 获取信号量失败（超时）</li>
                </ul>
                
                <p><strong>作用</strong>：获取（"拿取"）信号量</p>
                
                <p><strong>示例</strong>：</p>
                <pre><code>// 获取互斥信号量，阻塞等待
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
    // 成功获取互斥信号量，可以访问共享资源
    // ...
    
    // 释放互斥信号量
    xSemaphoreGive(xMutex);
}</code></pre>
                
                <h4>xSemaphoreGive - 释放信号量</h4>
                <div class="function-signature">
                    <pre><code>BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore);</code></pre>
                </div>
                
                <p><strong>返回值</strong>：</p>
                <ul>
                    <li>pdTRUE: 成功释放信号量</li>
                    <li>pdFALSE: 释放信号量失败</li>
                </ul>
                
                <p><strong>作用</strong>：释放（"给出"）信号量</p>
                
                <p><strong>示例</strong>：</p>
                <pre><code>// 在中断服务程序中给出二值信号量
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);

// 如果需要，进行上下文切换
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);</code></pre>
            </section>
            
            <div class="nav-links">
                <a href="chapter5.html">上一章：队列</a>
                <a href="chapter7.html">下一章：软件定时器</a>
            </div>
        </div>
    </div>

    <footer class="footer">
        <p>FreeRTOS学习笔记 &copy; 2025</p>
        <p>作者: zou.commit()</p>
    </footer>
</body>
</html>